import gulp from 'gulp';
import webpack from 'webpack-stream';
import runSequence from 'run-sequence';
import uglify from 'gulp-uglify';
import dependencyTree from 'dependency-tree';

let entries = {
    './public/dest': [
        {
            name: 'js/demo',
            file: './public/javascripts/demo.js'
        }
    ]
};
let webpackEntry = {};
let debug = false;

function getDependencies(path) {
    let folder = path.substr(0, path.lastIndexOf('/')),
        name = path.substr(path.lastIndexOf('/') + 1);
    return new Set(dependencyTree.toList({
        filename: `${folder}/${name}`,
        directory: folder,
        filter: (path) => { return path.indexOf('node_modules') === -1; }
    }));
}

function createFullEntry(isDebug) {
    debug = isDebug;
    for (let dest in entries) {
        webpackEntry[dest] = {};
        for (let item of entries[dest]) {
            webpackEntry[dest][item.name] = item.file;
        }
    }
}

function handleError(err) {
    console.log(err.toString());
    this.emit('end');
}

gulp.task('script-process', (callback) => {
    let stream = gulp.src('./package.json');

    for (let dest in webpackEntry) {
        stream = stream.pipe(webpack({
            entry: webpackEntry[dest],
            output: {
                filename: '[name].js',
            },
            devtool: debug ? '#source-map' : null,
            module: {
                loaders: [
                    {
                        test: /\.js$/,
                        exclude: /node_modules/,
                        loader: 'babel-loader'
                    }
                ]
            },
            resolve:{
                alias:{                    
                    'vue':'vue/dist/vue.js'
                }
            }
        }));
        if (!debug) {
            stream = stream.pipe(uglify());
        }
        stream = stream.pipe(gulp.dest(dest));
    }
    return stream;
});

gulp.task('build-script', (callback) => {
    createFullEntry(false);

    runSequence(['script-process'],
        callback);
});

gulp.task('build-script-dev', (callback) => {
    createFullEntry(true);

    runSequence(['script-process'],
        callback);
});

let fileStack = new Set(),
    collectTime = 500,
    pending = false;

function autoCompile() {
    try {
        debug = true;
        rebuildEntries();
        webpackEntry = {};
        for (let path of fileStack) {
            for (let dest in entries) {
                for (let item of entries[dest]) {
                    if (item.dependencies.has(path)) {
                        webpackEntry[dest] = webpackEntry[dest] || {};
                        webpackEntry[dest][item.name] = item.file;
                    }
                }
            }
        }
    } catch (e) { return; }

    fileStack.clear();
    pending = false;
    runSequence(['script-process']);
}

function rebuildEntries() {
    for (let dest in entries) {
        for (let item of entries[dest]) {
            item.dependencies = getDependencies(item.file);
        }
    }
}

gulp.task('auto-compile-script', (callback) => {
    let watcher = gulp.watch(
        ['./src/**/*.js'],
        (event) => {
            if (event.type != 'changed') {
                return;
            }
            fileStack.add(event.path);
            if (!pending) {
                pending = true;
                setTimeout(autoCompile, collectTime);
            }
        }
    );
});